package com.aaie.gru.picture.controller;


import com.aaie.gru.picture.entity.GruSysPicture;
import com.aaie.gru.picture.service.IGruSysPictureService;
import com.aaie.gru.position.entity.GruSysPositionGet;
import com.aaie.gru.problemresult.entity.GruSysProblemResult;
import com.aaie.gru.response.ResMessage;
import com.aaie.gru.util.CommonUtil;
import com.aaie.gru.util.OperateImage;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 图片 前端控制器
 * </p>
 *
 * @author lvxing
 * @since 2019-08-13
 */
@Api(tags = "图片上传、下载、删除模块")
@RestController
@RequestMapping("/picture")
public class GruSysPictureController {

    private static final Logger logger = LoggerFactory.getLogger(GruSysPictureController.class);

    @Value("${uploadPath}")
    private String uploadPath;

    private String fileFormatWithExt = "%s.%s";
    private String pathFormat = "%s%c%s%c";
    private static final String ENCODE = "UTF-8";

    @Autowired
    IGruSysPictureService gruSysPictureService;


    /**
     * 批量删除附件
     *
     * @return
     * @throws IOException
     */
    @ApiOperation(value = "批量删除附件", notes = "批量删除附件")
    @DeleteMapping("/batchRemove")
    public Object batchRemove(@RequestBody List<String> file_ids) {
        boolean obj = false;
        // 服务器文件路径
        try {
            for (String file_id : file_ids) {

                String filePath = this.getFilePathByFileID(file_id);
                String fileName = this.getFileNameByFileID(file_id);
                String fileRootPath = this.getFileRootPath();
                if (filePath != null && fileName != null && fileRootPath != null) {
                    // 服务器端文件全路径

                    File file = new File(fileRootPath + filePath, fileName);

                    if (file.exists()) {
                        file.delete();
                    }

                    obj = true;
                }
            }

        } catch (Exception e) {
            logger.error("", e);
            return ResMessage.error("删除失败",200);
        } finally {

        }
        return ResMessage.ok(obj);
    }


    /**
     * 删除附件
     *
     * @return
     * @throws IOException
     */
    @ApiOperation(value = "删除附件", notes = "删除附件")
    @PostMapping("/remove")
    public Object remove(@RequestBody  JSONObject param) {
        String file_id = param.getString("file_id");
        // 图片路径转换成图片id
        file_id = file_id.substring(0, 6).replace("\\", "_").replace("/", "_") + file_id.substring(6);
        boolean obj = false;
        // 服务器文件路径
        try {
            String filePath = this.getFilePathByFileID(file_id);
            logger.info("=============>>>>>>>>>>>>>>>>>File path:" + filePath);
            String fileName = this.getFileNameByFileID(file_id);
            logger.info("=============>>>>>>>>>>>>>>>>>File name:" + fileName);
            String fileRootPath = this.getFileRootPath() + File.separator;
            logger.info("=============>>>>>>>>>>>>>>>>>File root path:" + fileRootPath);
            if (filePath != null && fileName != null && fileRootPath != null) {
                // 服务器端文件全路径

                File file = new File(fileRootPath + filePath, fileName);

                if (file.exists()) {
                    file.delete();
                    obj = true;//文档删除使用
                }

                QueryWrapper<GruSysPicture> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("picture_path",param.getString("file_id"));
                boolean removePicture = gruSysPictureService.remove(queryWrapper);
                if(!removePicture){
                    return ResMessage.error("删除失败",500);
                }
            }
        } catch (Exception e) {
            logger.error("", e);
            return ResMessage.error("删除失败",200);
        } finally {

        }
        return ResMessage.ok(obj);
    }


    @ApiOperation(value = "文件上传", notes = "文件上传")
    @PostMapping(value = "/uploadFile")
    public String uploadFile(@RequestParam("inputText") MultipartFile fileInClient,@RequestParam("randomKey") String randomKey,@RequestParam("pictureType") String pictureType) {
        String fileId = "";
        String filepath = "";
        String originalFilename = "";
        String ext = "";
        long fileSize = 0;
        File fileInServer = null;
        //定义存储数据
        GruSysPicture gruSysPicture = new GruSysPicture();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(pictureType)){
            gruSysPicture.setPictureType(pictureType);
        }

        if(org.apache.commons.lang3.StringUtils.isNotBlank(randomKey)){
            gruSysPicture.setRandomKey(randomKey);
        }

        try {
            originalFilename = fileInClient.getOriginalFilename();
            // 文件名称
            gruSysPicture.setPictureName(originalFilename);
            fileSize = fileInClient.getSize();
            // 文件尺寸
            gruSysPicture.setPictureSize(String.valueOf(fileSize));

            int extIndex = originalFilename.lastIndexOf('.');
            if (originalFilename.length() - extIndex < 10) {
                ext = originalFilename.substring(extIndex + 1);
            }
            // 文件后缀
            gruSysPicture.setPictureSuffix(ext);
            String uuid = this.getUUID();
            if (uuid != null) {
                // 服务器端文件全路径
                String fileRootPath = this.getFileRootPath();
                String filePath = this.getFilePath(uuid);
                String fileName = this.getFileName(uuid, ext);
                fileInServer = new File(fileRootPath + File.separator + filePath, fileName);
                if (fileInServer != null) {
                    if (!fileInServer.getParentFile().exists()) {
                        fileInServer.getParentFile().mkdirs();
                    }

                    // MultipartFile自带的解析方法
                    fileInClient.transferTo(fileInServer);
                    filepath = (filePath + fileName);
                    fileId = (filePath + fileName).replace(File.separatorChar, '_');
                }
            }
            gruSysPicture.setPictureFileId(fileId.trim());
            gruSysPicture.setPicturePath(filepath.trim());
            String updateTime = CommonUtil.generateLocalDateTime();
            long updateTimeSort = CommonUtil.generateCurrentTimeMillis();
//            String username = CommonUtil.getUser().getUserName();
//            gruSysPicture.setCreateName(username);
            gruSysPicture.setCreateTime(updateTime);
            gruSysPicture.setCreateTimeSort(updateTimeSort);
//            gruSysPicture.setUpdateName(username);
            gruSysPicture.setUpdateTime(updateTime);
            gruSysPicture.setUpdateTimeSort(updateTimeSort);
            gruSysPictureService.save(gruSysPicture);
        } catch (Exception e) {
            logger.error("", e);
            return ResMessage.error("上传失败",200);
        }
        return ResMessage.ok(gruSysPicture);
    }

    @ApiOperation(value = "文件上传For ios", notes = "文件上传For ios")
    @PostMapping(value = "/uploadFileForIos")
    public String uploadFileForIos(@RequestBody GruSysProblemResult gruSysProblemResult){
        String imgStr = gruSysProblemResult.getProblemResultSignPath();
        imgStr = imgStr.replace("data:image/png;base64,","");
        imgStr = imgStr.replace("data:image/jpeg;base64,","");
        String fileId = "";
        String filepath = "";
        //对字节数组字符串进行Base64解码并生成图片
        //图像数据为空
        if (imgStr == null){
            return ResMessage.error("图片Base64为空",500);
        }

        BASE64Decoder decoder = new BASE64Decoder();
        try{
            //Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for(int i=0;i<b.length;++i){
                if(b[i]<0){//调整异常数据
                    b[i]+=256;
                }
            }
            String uuid = this.getUUID();
            String fileRootPath = this.getFileRootPath();
            String filePath = this.getFilePath(uuid);
            String fileName = this.getFileName(uuid, "jpg");
            File fileInServer = new File(fileRootPath + File.separator + filePath, fileName);
            if(fileInServer != null){
                if (!fileInServer.getParentFile().exists()) {
                    fileInServer.getParentFile().mkdirs();
                }

                OutputStream out = new FileOutputStream(fileRootPath + File.separator + filePath + File.separator + fileName);
                out.write(b);
                out.flush();
                out.close();

                filepath = (filePath + fileName);
                fileId = (filePath + fileName).replace(File.separatorChar, '_');
            }

            GruSysPicture gruSysPicture = new GruSysPicture();
            gruSysPicture.setPictureFileId(fileId.trim());
            gruSysPicture.setPicturePath(filepath.trim());
            gruSysPicture.setPictureName(fileName);
            String updateTime = CommonUtil.generateLocalDateTime();
            long updateTimeSort = CommonUtil.generateCurrentTimeMillis();
            gruSysPicture.setCreateTime(updateTime);
            gruSysPicture.setCreateTimeSort(updateTimeSort);
            gruSysPicture.setUpdateTime(updateTime);
            gruSysPicture.setUpdateTimeSort(updateTimeSort);
            gruSysPictureService.save(gruSysPicture);

            return ResMessage.ok(gruSysPicture);
        }catch (Exception e){
            return ResMessage.error("上传失败",500);
        }
    }

    @ApiOperation(value = "文件上传", notes = "文件上传")
    @PostMapping(value = "/uploadImage")
    public String uploadImage(@RequestParam("inputText") MultipartFile fileInClient, String left, String top, String x, String y,String randomKey) {

        String fileId = "";
        String filepath = "";
        String originalFilename = "";
        String ext = "";
        long fileSize = 0;
        File fileInServer = null;
        //定义存储数据
        GruSysPicture gruSysPicture = new GruSysPicture();
        gruSysPicture.setRandomKey(randomKey);
        try {
            originalFilename = fileInClient.getOriginalFilename();
            // 文件名称
            gruSysPicture.setPictureName(originalFilename);
            fileSize = fileInClient.getSize();
            // 文件尺寸
            gruSysPicture.setPictureSize(String.valueOf(fileSize));

            int extIndex = originalFilename.lastIndexOf('.');
            if (originalFilename.length() - extIndex < 10) {
                ext = originalFilename.substring(extIndex + 1);
            }
            // 文件后缀
            gruSysPicture.setPictureSuffix(ext);
            String uuid = this.getUUID();
            String path = "";
            if (uuid != null) {
                // 服务器端文件全路径
                String fileRootPath = this.getFileRootPath();
                String filePath = this.getFilePath(uuid);
                String fileName = this.getFileName(uuid, ext);
                path = fileRootPath + File.separator + filePath + fileName;
                fileInServer = new File(fileRootPath + File.separator + filePath, fileName);
                if (fileInServer != null) {
                    if (!fileInServer.getParentFile().exists()) {
                        fileInServer.getParentFile().mkdirs();
                    }

                    // MultipartFile自带的解析方法
                    fileInClient.transferTo(fileInServer);
                    filepath = (filePath + fileName);
                    fileId = (filePath + fileName).replace(File.separatorChar, '_');
                }
                //如果是文件需要切图

                OperateImage operateImage = new OperateImage(path, path, ext, Integer.parseInt(x), Integer.parseInt(y), Integer.parseInt(left), Integer.parseInt(top));
                operateImage.cut();

                CommonUtil.zoomImage(path, path, Integer.parseInt(left), Integer.parseInt(top));
            }
            gruSysPicture.setPictureFileId(fileId.trim());
            gruSysPicture.setPicturePath(filepath.trim());
            String updateTime = CommonUtil.generateLocalDateTime();
            long updateTimeSort = CommonUtil.generateCurrentTimeMillis();
//            String username = CommonUtil.getUser().getUserName();
//            gruSysPicture.setCreateName(username);
            gruSysPicture.setCreateTime(updateTime);
            gruSysPicture.setCreateTimeSort(updateTimeSort);
//            gruSysPicture.setUpdateName(username);
            gruSysPicture.setUpdateTime(updateTime);
            gruSysPicture.setUpdateTimeSort(updateTimeSort);
            gruSysPictureService.save(gruSysPicture);
        } catch (Exception e) {
            logger.error("", e);
            return ResMessage.error("上传失败", 200);
        }
        return ResMessage.ok(gruSysPicture);
    }



    /**
     * 文件下载功能
     *
     * @param response
     * @throws Exception
     */
    @ApiOperation(value = "文件下载", notes = "文件下载")
    @PostMapping("/download")
    public void download(@RequestBody JSONObject param, HttpServletResponse response) throws Exception {
        String file_id = param.getString("file_id");
        // 图片路径转换成图片id
        file_id = file_id.substring(0, 6).replace("\\", "_").replace("/", "_") + file_id.substring(6);
        BufferedOutputStream out = null;
        InputStream bis = null;
        File fileInServer = null;
        try {

            String filePath = this.getFilePathByFileID(file_id);
            String fileName = this.getFileNameByFileID(file_id);
            String fileRootPath = this.getFileRootPath() + File.separator;

            if (filePath != null && fileName != null && fileRootPath != null) {
                // 服务器端文件全路径

                fileInServer = new File(fileRootPath + filePath, fileName);
                // 获取输入流
                bis = new BufferedInputStream(new FileInputStream(fileInServer));

                // 转码，免得文件名中文乱码
                String fileNameForUTF8 = URLEncoder.encode(fileName, ENCODE);
                // 设置文件下载头
                response.addHeader("Content-Disposition", "attachment;filename=" + fileNameForUTF8);

                // 1.设置文件ContentType类型，这样设置，会自动判断下载文件类型
                response.setContentType("multipart/form-data");
                out = new BufferedOutputStream(response.getOutputStream());
                int len = 0;
                while ((len = bis.read()) != -1) {
                    out.write(len);
                    out.flush();
                }
            }
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            if (bis != null) {
                bis.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }

    private String getUUID() {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // char[] cs = uuid.toCharArray();
        if (uuid != null && uuid.length() == 32) {
            return uuid;
        }
        return null;
    }

    private String getFileName(String uuid, String ext) {
        if (ext == null || ext.trim().length() == 0) {
            return uuid;
        } else {
            return String.format(this.fileFormatWithExt, uuid, ext);
        }
    }

    private String getFilePathByFileID(String fileID) {
        if (fileID != null && fileID.length() > 6) {
            String first = fileID.substring(0, 2);
            String second = fileID.substring(3, 5);
            return String.format(this.pathFormat, first, File.separatorChar, second, File.separatorChar);
        }
        return null;
    }

    private String getFileNameByFileID(String fileID) {
        if (fileID != null && fileID.length() > 6) {
            return fileID.substring(6);
        }
        return null;
    }

    private String getFileRootPath() {
        String path = uploadPath;
//		String path = serverConfig.getAttachmentPath();
        if (path.endsWith(File.separator)) {
            path = path.substring(0, path.length() - 1);
        }
        return path;
    }

    private String getFilePath(String uuid) {

        int first = 0;
        for (int i = 0; i < 16; i++) {
            first += Integer.parseInt(uuid.substring(i, i + 1), 16);
        }
        int second = 0;

        for (int i = 16; i < 32; i++) {
            second += Integer.parseInt(uuid.substring(i, i + 1), 16);
        }

        if (first < 255 && first >= 0 && second < 255 && second >= 0) {
            return String.format(this.pathFormat, Integer.toHexString(first), File.separatorChar,
                    Integer.toHexString(second), File.separatorChar);
        }

        return null;
    }

    @GetMapping("/getPictureById")
    public String getPictureById(String id) {
        return ResMessage.ok(gruSysPictureService.getById(id));
    }

    @ApiOperation(value = "按randomKey获取图片信息，获取完之后randomKey的值会变成-1", notes = "按randomKey获取图片信息，获取完之后randomKey的值会变成-1")
    @GetMapping("/getPictureByRandomKey")
    public String getPictureByRandomKey(String randomKey) {
        try {
            QueryWrapper<GruSysPicture> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("random_key", randomKey);
            GruSysPicture gruSysPicture = gruSysPictureService.getOne(queryWrapper);
            // -1代表此图片已经返回给前端过
            gruSysPicture.setRandomKey("-1");
            gruSysPictureService.saveOrUpdate(gruSysPicture);
            return ResMessage.ok(gruSysPicture);
        } catch (Exception e) {
            e.printStackTrace();
            return ResMessage.error("按随机唯一字符串获取图片信息失败", 200);
        }
    }

    @ApiOperation(value = "获取轮播图片", notes = "获取轮播图片")
    @GetMapping("/getPictureByPictureType")
    public String getPictureByPictureType(String pictureType){
        QueryWrapper<GruSysPicture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("picture_type",pictureType);
        List<GruSysPicture> pictureList = gruSysPictureService.list(queryWrapper);
        return ResMessage.ok(pictureList);
    }
}
